using System;
using System.Threading;

namespace Nice157Advices.Advices
{
    /// <summary>
    /// 76.警惕线程的优先级
    /// 77.正确停止线程
    /// 79.使用ThreadPool 或BackgroundWorker 代替Thread 
    /// </summary>
    public static class _76
    {
        /**
         * 76.
         * 在C#中，使用Thread 和ThreadPool 新起的线程，默认优先级都是Normal。虽然可以像上面的示例那样去修改线程的优先级，但是一般不建议这样做。当然，如果是一些非常关键的线程，我们还是可以提升线程的优先级的。这些关键线程应当具有运行时间短、能即刻进入等待状态等特征。
         * 
         * 77.
         * 
         * 79. 线程的开销是很大的（包括空间开销和时间开销），微软为此开发了“线程池”技术，帮开发人员管理工作线程。所以我们要多线程编程时不应该想到 new Thread 的方式，而是首先想到依赖线程池。
         * 当然ThreadPool 也存在一些不方便的地方，具体看建议80
         */
        public static void Go ()
        {
            long t1Num = 0;
            long t2Num = 0;
            // 77.
            CancellationTokenSource cta = new CancellationTokenSource ();
            Thread t1 = new Thread (() =>
            {
                while (true && !cta.Token.IsCancellationRequested)
                {
                    t1Num++;
                }
            });
            t1.IsBackground = true;
            t1.Priority = ThreadPriority.Highest;   // 提高优先级
            t1.Start ();

            // Thread t2 = new Thread (() =>
            // {
            //     while (true && !cta.Token.IsCancellationRequested)
            //     {
            //         t2Num++;
            //     }
            // });
            // t2.IsBackground = true;
            // t2.Start ();

            // 使用线程池进行多线程编程
            ThreadPool.QueueUserWorkItem((objState) => {
                while (true && !cta.Token.IsCancellationRequested) {
                    t2Num++;
                }
            }, null);

            Thread.Sleep(100);

            //停止线程
            cta.Cancel ();
            cta.Token.Register(() => {
                System.Console.WriteLine("工作线程被停止了");
            });
            
            Console.WriteLine ("t1Num:" + t1Num.ToString ());
            Console.WriteLine ("t2Num:" + t2Num.ToString ());
        }
    }
}